home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 25
/
Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso
/
Aminet
/
game
/
shoot
/
ADoom_src_1_2.lha
/
ADoom_src
/
amiga_music.s
< prev
next >
Wrap
Text File
|
1998-02-28
|
42KB
|
1,925 lines
mc68020
; multipass
; if (_eval(DEBUG)&$8000)
; debug on,lattice4
; endc
; 2 channel .MUS player
;
; Derived by Peter McGavin,
; mostly by cutting and pasting large chunks of code from Amiga .MUS player
; originally by Joseph Fenton, Microcode Solutions, jlfenton@ctaz.com
; and his brother Michael.
; void I_InitMusic (void);
; void I_ShutdownMusic (void);
; void I_SetMusicVolume (int volume); // Volume.
; void I_PauseSong (int handle); // PAUSE game handling.
; void I_ResumeSong (int handle);
; int I_RegisterSong (void *data); // Registers a song handle to song data.
;// Called by anything that wishes to start music.
;// plays a song, and when the song is done,
;// starts playing it again in an endless loop.
;// Horrible thing to do, considering.
; void I_PlaySong (int handle, int looping);
; void I_StopSong (int handle); // Stops a song over 3 seconds.
; void I_UnRegisterSong (int handle); // See above (register), then think backwards
;------------------------------------------------------------------------
xdef @I_InitMusic ; Allocate audio channels and clear them.
xdef @I_ShutdownMusic ; Clear channels and free them.
xdef @I_SetMusicVolume ; Do code equiv to J_VolBox.
xdef @I_PauseSong ; Do code equiv to DoPause.
xdef @I_ResumeSong ; Goes to J_PlayBox equiv code.
xdef @I_RegisterSong ; Do code equiv to LoadMUS; no need to actually load it
; as we are passed a pointer to it here.
xdef @I_PlaySong ; Do code equiv to J_PlayBox.
xdef @I_StopSong ; Do code equiv to J_StopBox.
xdef @I_UnRegisterSong ; Do code equiv to FreeUpMUS.
;-----------------------------------------------------------------------
section text,code
near a4,-2
;------------------------------------------------------------------------
xref _SysBase
xref _DOSBase
xref _GfxBase
xref _custom
xref _snd_MusicVolume
xref _gametic
xref _I_Error
xref @M_CheckParm
;------------------------------------------------------------------------
include "exec/types.i"
include "exec/memory.i"
include "exec/funcdef.i"
include "exec/exec_lib.i"
include "dos/dos.i"
include "dos/dos_lib.i"
include "graphics/gfxbase.i"
include "devices/audio.i"
include "hardware/custom.i"
include "hardware/intbits.i"
TICRATE equ 35 ; see doomdef.h
CALLSYS macro ;FunctionName
jsr _LVO\1(a6)
endm
CALLEXE macro ;FunctionName
movea.l (_SysBase),a6
jsr _LVO\1(a6)
endm
CALLDOS macro ;FunctionName
movea.l (_DOSBase),a6
jsr _LVO\1(a6)
endm
;_LVOCreatePool equ -696 ; not in Macro68's autoincludes
;_LVODeletePool equ -702 ; not in Macro68's autoincludes
;------------------------------------------------------------------------
; void I_InitMusic (void);
; Allocate audio channels and clear them.
@I_InitMusic movem.l d0-d7/a0-a6,-(sp)
movea.l #musicarg,a0
jsr @M_CheckParm
tst.l d0
beq .exit
suba.l a1,a1 ; this task
CALLEXE FindTask
move.l d0,AudioTask ; set task to signal
move.w #162,(per)
move.w #325,(per2) ; 11025 Hz, NTSC
move.l (_GfxBase),a6
move.w (gb_DisplayFlags,a6),d0
btst #PALn,d0
beq.b 2$
move.w #161,(per)
move.w #322,(per2) ; 11025 Hz, PAL
2$
moveq #0,d0
moveq #0,d1
lea AudioName,a0
lea AudioIO,a1
clr.l ioa_Length(a1) ; don't allocate channels yet
CALLEXE OpenDevice
tst.l d0
beq 1$
move.l #cantopenaud,-(sp)
jsr _I_Error
bra .exit
1$ move.b #-1,AudioOK
bsr AllocChannels ; allocate channels
.exit
movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; void I_ShutdownMusic (void);
; Clear channels and free them.
@I_ShutdownMusic
movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .exit
bsr @I_StopSong
bsr @I_UnRegisterSong ; kill old mus
bsr FreeChannels
lea AudioIO,a1
CALLEXE CloseDevice
clr.b AudioCh
clr.b AudioOK
.exit movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; void I_SetMusicVolume (int volume); // Volume.
; Do code equiv to J_VolBox.
@I_SetMusicVolume
movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .exit
move.l d0,(_snd_MusicVolume)
lsl.w #3,d0 ; * 8
move.w d0,AudioCh2Vol
move.w d0,AudioCh3Vol
.exit movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; void I_PauseSong (int handle); // PAUSE game handling.
; Do code equiv to DoPause.
@I_PauseSong movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .done
btst #1,Flags ; file loaded?
beq.b .done
bset #0,MusFlag ; stop
bclr #2,Flags ; playing?
beq.b .done
.stop btst #0,MusFlag ; music stopped?
bne.b .stop
cmpi.b #12,AudioCh ; locked?
bne.b .done
lea _custom,a0 ; kill sound
moveq #0,d0
move.w d0,aud2+ac_vol(a0)
move.w d0,aud3+ac_vol(a0)
.done movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; void I_ResumeSong (int handle);
; Goes to J_PlayBox equiv code.
@I_ResumeSong movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .exit
btst #1,Flags ; file loaded?
beq.b .nofile
cmpi.b #12,AudioCh ; got all channels?
beq.b .allch
bsr AllocChannels ; try to alloc, first
cmpi.b #12,AudioCh ; now?
beq.b .allch
move.l #cantgetchan,-(sp)
jsr _I_Error
bra .exit
.allch bset #2,Flags ; playing?
beq.b .ok
.nofile rts
.ok movea.l MusPtr,a0
moveq #0,d1
move.b 8(a0),d1 ; d1 = # of channels
moveq #0,d0
move.w 6(a0),d0 ; score start
ror.w #8,d0
adda.l d0,a0 ; a0 = start
bclr #3,Flags ; paused?
bne .paused
move.l a0,MusIndex ; MusIndex = start
move.l #QuietInst,Channel0
move.l #QuietInst,Channel1
move.l #QuietInst,Channel2
move.l #QuietInst,Channel3
move.l #QuietInst,Channel4
move.l #QuietInst,Channel5
move.l #QuietInst,Channel6
move.l #QuietInst,Channel7
move.l #QuietInst,Channel8
move.l #QuietInst,Channel9
move.l #QuietInst,Channel10
move.l #QuietInst,Channel11
move.l #QuietInst,Channel12
move.l #QuietInst,Channel13
move.l #QuietInst,Channel14
move.l #QuietInst,Channel15
clr.l MusDelay ; MusDelay = 0
clr.b MusFlag ; enable music
clr.l VoiceAvail ; all voices available
clr.l MyTicks ; reset my timer
.paused CALLEXE Disable
lea _custom,a0
move.w #$8200,intena(a0) ; int enable
move.w #$800c,dmacon(a0) ; enable dma
bsr AudioINT2 ; start audio
CALLSYS Enable
.exit movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; int I_RegisterSong (void *data); // Registers a song handle to song data.
; Do code equiv to LoadMUS; no need to actually load it
; as we are passed a pointer to it here.
@I_RegisterSong
movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .done2
move.l a0,-(sp) ; save data ptr
bsr @I_StopSong ; stop current mus
bsr @I_UnRegisterSong ; kill old mus
movea.l (sp)+,a0
move.l a0,MUSMemPtr
cmpi.l #$4D55531A,(a0) ; "MUS",26
bne .uerror ; not a mus file
move.l MUSMemPtr(pc),MusPtr
bsr TestMUSFile
beq .berror
;--------
move.l InstrFile,d1
move.l #MODE_OLDFILE,d2
CALLDOS Open
move.l d0,InstrHandle
beq .midierror
move.l #MEMF_CLEAR,d0 ; any memory
move.l #65536,d1 ; puddle size
move.l #32768,d2 ; threshold size
bsr CreatePool
move.l a0,InstrPool ; this was d0
beq .merror
movea.l a0,a2 ; so was this
movea.l MusPtr,a3
move.w #255,d0
lea Instruments,a0
.setinstr move.l #QuietInst,(a0)+
dbra d0,.setinstr
move.w $C(a3),d4 ; instrCnt
ror.w #8,d4
subq.w #1,d4 ; for dbra
lea $10(a3),a3 ; instruments[]
.instrloop moveq #14,d0
movea.l a2,a0
bsr AllocPooled
moveq #0,d2
move.b (a3)+,d2 ; instrument #
moveq #0,d1
move.b (a3)+,d1 ; offset to next instr. #
adda.l d1,a3 ; skip it (whatever it is?)
lea Instruments,a0
move.l d0,(a0,d2.w*4)
beq .merror
movea.l d0,a4 ; instrument record
bftst (validInstr){d2:1}
beq .next ; no instrument
move.l InstrHandle,d1
lsl.l #2,d2
moveq #OFFSET_BEGINNING,d3
CALLDOS Seek
move.l InstrHandle,d1
move.l a4,d2
moveq #4,d3
CALLSYS Read ; get instrument offset
addq.l #1,d0
beq .ferror ; can't read file
move.l InstrHandle,d1
move.l (a4),d2
moveq #OFFSET_BEGINNING,d3
CALLSYS Seek
move.l InstrHandle,d1
move.l a4,d2
moveq #14,d3
CALLSYS Read ; get instrument header
addq.l #1,d0
beq .ferror ; can't read file
move.l in_Length(a4),d0
swap d0
movea.l a2,a0
bsr AllocPooled
move.l d0,in_Wave(a4) ; wave data buffer
beq .merror
move.l InstrHandle,d1
move.l d0,d2
move.l in_Length(a4),d3
swap d3
CALLDOS Read ; get instrument samples
addq.l #1,d0
beq .ferror ; can't read file
move.b #1,in_Flags(a4)
.next dbra d4,.instrloop
bset #1,Flags ; file loaded
bsr FillEventBlocks
.done btst #1,Flags ; success?
bne.b .exit
bsr @I_UnRegisterSong ; kill MUS and instruments
.exit move.l InstrHandle,d1
beq.b .done2
CALLDOS Close
clr.l InstrHandle
.done2 moveq #1,d0 ; return handle=1
movem.l (sp)+,d0-d7/a0-a6
rts
;---------
.midierror move.l #midifileproblem,-(sp)
jsr _I_Error
bra .done
.ferror move.l #dosproblem,-(sp)
jsr _I_Error
bra .done
.merror move.l #memproblem,-(sp)
jsr _I_Error
bra .done
.uerror move.l #notmusfile,-(sp)
jsr _I_Error
bra .done
.berror move.l #damagedfile,-(sp)
jsr _I_Error
bra .done
;------------------------------------------------------------------------
;// Called by anything that wishes to start music.
;// plays a song, and when the song is done,
;// starts playing it again in an endless loop.
;// Horrible thing to do, considering.
; void I_PlaySong (int handle, int looping);
; Do code equiv to J_PlayBox.
@I_PlaySong movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .exit
move.l #TICRATE*30,d0
add.l (_gametic),d0
move.l d0,(musicdies)
bsr @I_ResumeSong
.exit movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; void I_StopSong (int handle); // Stops a song over 3 seconds.
; Do code equiv to J_StopBox.
@I_StopSong movem.l d0-d7/a0-a6,-(sp)
move.l #0,(looping)
move.l #0,(musicdies)
tst.b AudioOK
beq .exit
bsr @I_PauseSong
bsr KillAllAud
.exit movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
; void I_UnRegisterSong (int handle); // See above (register), then think backwards
; Do code equiv to FreeUpMUS.
@I_UnRegisterSong
movem.l d0-d7/a0-a6,-(sp)
tst.b AudioOK
beq .free
bclr #1,Flags ; still have anything?
beq.b .free
clr.l MUSMemPtr
clr.l MUSMemSize
.instr tst.l InstrPool
beq.b .free
movea.l InstrPool,a0
bsr DeletePool
clr.l InstrPool
.free movem.l (sp)+,d0-d7/a0-a6
rts
;------------------------------------------------------------------------
;------------------------------------------------------------------------
FillEventBlocks lea EventBlocks,a4
movea.l MusPtr(pc),a0
move.w 6(a0),d0
ror.w #8,d0
lea (a0,d0.w),a2 ; a2 = start
movea.l a2,a1 ; a1 = a2
.loop bsr NextDelay
move.l a1,d0
sub.l a2,d0 ; d0 = ptr - start
move.w d0,(a4)+ ; store
addq.l #1,d1
bne.b .loop
clr.w (a4) ; end of offsets
rts
NextDelay bsr.b MyNextEvent
cmpi.b #6,d1 ; score end
beq.b .dd
tst.b d0
bpl.b NextDelay
moveq #0,d1 ; time = 0
.d1 move.b (a1)+,d0 ; get byte
bpl.b .d2
andi.w #$7F,d0 ; kill sign bit
or.b d0,d1 ; time = time + 7 bits
lsl.l #7,d1 ; * 128
bra.b .d1 ; get next 7 bits
.d2 or.b d0,d1 ; time = time + last 7 bits
rts
.dd moveq #-1,d1
rts
MyNextEvent move.b (a1)+,d0 ; d0 = event
moveq #$70,d1
and.b d0,d1 ; d1 = type<<4
bne.b .e1
.e0 addq.l #1,a1 ; + value
rts
.e1 lsr.b #4,d1 ; d1 = type
cmpi.b #6,d1 ; score end?
bne.b .e2
subq.l #1,a1
.ed rts
.e2 cmpi.b #5,d1 ; no event
beq.b .ed
cmpi.b #7,d1 ; no event
beq.b .ed
cmpi.b #1,d1 ; play
beq.b .ep
cmpi.b #4,d1 ; change?
bne.b .e0
addq.l #2,a1 ; + value1, value2
rts
.ep moveq #0,d4
tst.b (a1)+ ; + note
bmi.b .e0 ; (+ volume, if b7 set)
rts
moveq #1,d0
rts
;------------------------------------------------------------------------
TestMUSFile movea.l MusPtr(pc),a0
move.l MUSMemSize(pc),d3 ; d3 = total file size
moveq #0,d0
move.w 4(a0),d0
beq .fail
ror.w #8,d0 ; score length
moveq #0,d1
move.w 6(a0),d1
ror.w #8,d1 ; score start
cmpi.w #18,d1 ; start < 18? (1 instr.)
blt .fail
add.l d1,d0 ; d0 = total size
; cmp.l d0,d3 ; = file size?
; bne .fail
move.l d0,d3
move.l d3,MUSMemSize
move.w 12(a0),d2
beq.b .fail
ror.w #8,d2 ; d2 = instr. count
subq.w #1,d2
lea 16(a0),a1 ; a1 = * instr. list
.loop addq.l #1,a1 ; skip instr. value
moveq #0,d0
move.b (a1)+,d0 ; d0 = offset to next instr.
adda.l d0,a1 ; skip info (?)
dbra d2,.loop ; next
move.l a1,d0 ; d0 = * data following list
sub.l a0,d0 ; - file start
cmp.l d0,d1 ; = start?
bne.b .fail
move.b -1(a0,d3.l),d0 ; get last byte
lsr.b #4,d0
cmpi.b #6,d0 ; last byte = $6x? (end)
bne.b .fail
moveq #1,d0 ; file okay
rts
.fail moveq #0,d0 ; yikes!
rts
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; stop, clear, turn off
KillAllAud cmpi.b #12,AudioCh ; locked?
bne.b .vk
lea _custom,a0
move.l #ClearBuf,aud2(a0) ; re-init
move.w #80,aud2+ac_len(a0)
move.w (per,pc),aud2+ac_per(a0)
move.l #ClearBuf,aud3(a0)
move.w #80,aud3+ac_len(a0)
move.w (per,pc),aud3+ac_per(a0)
.vk clr.b Voice0+vc_Flags ; disable voices
clr.b Voice1+vc_Flags
clr.b Voice2+vc_Flags
clr.b Voice3+vc_Flags
clr.b Voice4+vc_Flags
clr.b Voice5+vc_Flags
clr.b Voice6+vc_Flags
clr.b Voice7+vc_Flags
clr.b Voice8+vc_Flags
clr.b Voice9+vc_Flags
clr.b Voice10+vc_Flags
clr.b Voice11+vc_Flags
clr.b Voice12+vc_Flags
clr.b Voice13+vc_Flags
clr.b Voice14+vc_Flags
clr.b Voice15+vc_Flags
rts
;------------------------------------------------------------------------
;------------------------------------------------------------------------
AllocChannels lea AudioIO,a1
move.w #ADCMD_ALLOCATE,IO_COMMAND(a1)
move.b #ADIOF_NOWAIT+IOF_QUICK,IO_FLAGS(a1)
move.l #AudioAlloc,ioa_Data(a1)
move.l #1,ioa_Length(a1)
movea.l IO_DEVICE(a1),a6
jsr DEV_BEGINIO(a6)
tst.l d0
beq 1$
move.l #cantgetchan,-(sp)
jsr _I_Error
bra .exit
1$ lea AudioIO,a1
move.w #ADCMD_LOCK,IO_COMMAND(a1)
CALLEXE SendIO
move.l AudioIO+IO_UNIT,d0
move.b d0,AudioCh
cmpi.b #12,d0 ; all channels?
beq 2$
move.l #cantgetchan,-(sp)
jsr _I_Error
bra .exit
2$ lea _custom,a0
move.w #$0600,intena(a0) ; kill int enable
move.w #$0600,intreq(a0) ; kill request
move.w #$00FF,adkcon(a0) ; kill modulation
move.w #$000C,dmacon(a0) ; disable dma
move.l #ClearBuf,aud2(a0)
move.w #80,aud2+ac_len(a0)
move.w (per,pc),aud2+ac_per(a0)
move.w #0,aud2+ac_vol(a0)
move.l #ClearBuf,aud3(a0)
move.w #80,aud3+ac_len(a0)
move.w (per,pc),aud3+ac_per(a0)
move.w #0,aud3+ac_vol(a0)
moveq #INTB_AUD2,d0
lea AInt2,a1
CALLEXE SetIntVector
move.l d0,OldAInt2
.exit rts
;------------------------------------------------------------------------
FreeChannels cmpi.b #12,AudioCh
bne.b .exit ; no channels
lea _custom,a0
move.w #$0600,intena(a0) ; kill int enable
move.w #$0600,intreq(a0) ; kill request
moveq #INTB_AUD2,d0
movea.l OldAInt2,a1
CALLEXE SetIntVector
moveq #$000c,d0
move.w d0,_custom+dmacon ; dma off
lea AudioIO,a1
move.w #ADCMD_FREE,IO_COMMAND(a1)
move.b #IOF_QUICK,IO_FLAGS(a1)
movea.l IO_DEVICE(a1),a6
jsr DEV_BEGINIO(a6)
clr.l AudioIO+IO_UNIT
clr.b AudioCh
.exit rts
;--------------------------------------------------------------------
cnop 0,16
AudioINT2 movem.l d2-d6/a2-a4/a6,-(a7)
btst #0,MusFlag
beq.b .cont
lea _custom,a0
move.w #$0600,intena(a0) ; kill int enable
move.w #$0600,intreq(a0) ; kill request
clr.b MusFlag
bra .exit
.cont subq.l #1,MusDelay
bpl.b .setaudio
bsr NextEvent
.setaudio bchg #1,MusFlag ; switch buffers
btst #6,Flags ; gadget down?
bne.b .gad
addq.l #1,MyTicks ; increment my timer
.gad lea Voice0,a0 ; music voices
lea AudioCh2Buf,a2
bsr FillBuffer
lea _custom,a0
move.w #INTF_AUD2,intreq(a0)
move.l AudioCh2Ptr,aud2(a0)
move.w #40,aud2+ac_len(a0) ; 80 samples
move.w (per2,pc),aud2+ac_per(a0) ; 11048Hz
move.w AudioCh2Vol,aud2+ac_vol(a0)
move.l AudioCh2Ptr,aud3(a0)
move.w #40,aud3+ac_len(a0) ; 80 samples
move.w (per2,pc),aud3+ac_per(a0) ; 11048Hz
move.w AudioCh2Vol,aud3+ac_vol(a0)
.exit movem.l (a7)+,d2-d6/a2-a4/a6
moveq #0,d0
rts
;------------------------------------------------------------------------
CNOP 0,16
FillBuffer moveq #0,d0
btst #1,MusFlag
beq.b .swap
move.l #80,d0
.swap movea.l (a2),a4 ; chip buffer
adda.l d0,a4
move.l a4,4(a2) ; AudioChxPtr
lea tempAudio,a1
moveq #4,d0
.cloop clr.l (a1)+
clr.l (a1)+
clr.l (a1)+
clr.l (a1)+
dbra d0,.cloop
.next move.l vc_Next(a0),d0 ; next voice
bne.b .chkvoice
lea tempAudio,a1
moveq #4,d0
.mloop move.l (a1)+,(a4)+
move.l (a1)+,(a4)+
move.l (a1)+,(a4)+
move.l (a1)+,(a4)+
dbra d0,.mloop
rts
.chkvoice movea.l d0,a0
btst #0,vc_Flags(a0)
beq.b .next ; not enabled
;------------------
; do voice
lea tempAudio,a1
btst #1,vc_Flags(a0)
beq.b .1 ; not releasing
subq.b #1,vc_Vol(a0)
bpl.b .1
clr.b vc_Vol(a0)
clr.b vc_Flags(a0) ; voice off
bra.b .next
.1 move.b vc_Vol(a0),d5
bfffo d5{24:8},d5 ; 0-127 -> 32-24
subi.b #24,d5 ; 8-0
addq.b #2,d5 ; /4
movem.l vc_Index(a0),d1-d4 ; index,step,loop,length
movea.l vc_Channel(a0),a3
move.l ch_Pitch(a3),d0
muls.l d0,d6:d2
move.w d6,d2
swap d2
add.l vc_Step(a0),d2 ; final sample rate
movea.l vc_Wave(a0),a3 ; sample data
moveq #79,d6 ; 80 samples
.floop moveq #0,d0
swap d1
move.b (a3,d1.w),d0 ; sample
swap d1
asr.b d5,d0
add.b d0,(a1)+
add.l d2,d1
cmp.l d4,d1
blo.b .2
sub.l d4,d1
add.l d3,d1
tst.l d3
beq.b .3 ; no looping
.2 dbra d6,.floop
bra.b .done ; done with voice 1
; ran out of data
.3 clr.b vc_Flags(a0) ; voice off
.done move.l d1,vc_Index(a0)
bra .next
;------------------------------------------------------------------------
CNOP 0,16
NextEvent movea.l MusIndex,a1
.0 move.b (a1)+,d0 ; get next event
move.b d0,d1
lsr.b #3,d1
andi.w #$E,d1 ; d1 = event type * 2
lea EventTable,a0
move.w (a0,d1.w),d1
jsr (a0,d1.w) ; do event
tst.b d0
bpl.b .0 ; more events
moveq #0,d1 ; time = 0
.1 move.b (a1)+,d0 ; get byte
bpl.b .2
andi.w #$7F,d0 ; kill sign bit
or.b d0,d1 ; time = time + 7 bits
lsl.l #7,d1 ; * 128
bra.b .1 ; get next 7 bits
.2 or.b d0,d1 ; time = time + last 7 bits
subq.l #1,d1 ; delay = time - 1
bmi.b .0 ; (no delay)
btst #6,Flags ; gadget down?
beq.b .nogad
btst #7,Flags
beq.b .rev
add.l d1,MyTicks ; add to my timer
addq.l #1,MyTicks ; + 1
lsr.l #3,d1 ; delay = delay / 8
bra.b .nogad
.rev bsr.b PrevBlock
.nogad move.l d1,MusDelay ; store delay
move.l a1,MusIndex ; store index
rts
PrevBlock move.l PrevDelay,d0
sub.l d0,MyTicks ; sub previous value
addq.l #1,d1
move.l d1,PrevDelay
move.l a1,d1 ; d1 = current ptr
movea.l MusPtr(pc),a0
move.w 6(a0),d0
ror.w #8,d0
lea (a0,d0.w),a0 ; a0 = start
cmp.l a0,d1 ; at start?
beq.b .done
lea EventBlocks,a1
.loop moveq #0,d0
move.w (a1)+,d0 ; offset
beq.b .done ; (not found)
add.l a0,d0 ; ptr
cmp.l d1,d0 ; = current?
bne.b .loop
subq.l #4,a1
cmpa.l #EventBlocks,a1 ; 2nd block?
bls.b .done
moveq #0,d0
move.w -(a1),d0 ; offset prev block
add.l a0,d0
movea.l d0,a1 ; ptr = prev block
moveq #0,d1 ; delay = 0
rts
.done movea.l a0,a1 ; ptr = start
moveq #0,d1 ; delay = 0
clr.l MyTicks ; reset timer
rts
;------------------------------------------------------------------------
Release moveq #15,d1
and.b d0,d1 ; d1 = channel
lea Channels,a0
movea.l (a0,d1.w*4),a0 ; channel record
movea.l ch_Map(a0),a0 ; channel map
move.b (a1)+,d1 ; note #
moveq #0,d2
move.b (a0,d1.w),d2 ; voice #
beq.b .exit ; no mapping
clr.b (a0,d1.w) ; clear mapping
move.l VoiceAvail,d3
bclr d2,d3 ; voice free for use
move.l d3,VoiceAvail
lea Voices,a0
movea.l (a0,d2.w*4),a0 ; voice
bset #1,vc_Flags(a0) ; do release
.exit rts
;------------------------------------------------------------------------
PlayNote moveq #15,d1
and.b d0,d1 ; d1 = channel
lea Channels,a0
movea.l (a0,d1.w*4),a2 ; channel record
movea.l ch_Map(a2),a0 ; channel map
moveq #-1,d2 ; no volume change
move.b (a1)+,d1 ; note #
bclr #7,d1
beq.b .getvc ; no volume
moveq #0,d2
move.b (a1)+,d2 ; volume
.getvc moveq #0,d3
move.l VoiceAvail,d4
.vloop bset d3,d4
beq.b .foundfree
addq.b #1,d3
cmpi.b #16,d3
bne.b .vloop
; no free voices
rts
.foundfree move.b d3,(a0,d1.w) ; voice mapping
move.l d4,VoiceAvail
lea Voices,a0
movea.l (a0,d3.w*4),a3 ; voice
btst #7,vc_Flags(a3)
bne.b .exit ; sfx using channel
tst.b d2
bmi.b .skip
move.b d2,ch_Vol(a2) ; new channel volume
.skip move.b ch_Vol(a2),vc_Vol(a3)
moveq #15,d2
and.b d0,d2
cmpi.b #15,d2
beq.b .percussion
move.l ch_Instr(a2),a4 ; instrument record
lea NoteTable,a0
moveq #72,d2 ; middle c
sub.b in_Base(a4),d2
add.b d1,d2
move.l (a0,d2.w*4),vc_Step(a3) ; step value for note
clr.l vc_Index(a3)
move.l a2,vc_Channel(a3) ; back link (for pitch wheel)
move.l in_Wave(a4),vc_Wave(a3)
move.l in_Loop(a4),vc_Loop(a3)
move.l in_Length(a4),vc_Length(a3)
move.b in_Flags(a4),vc_Flags(a3)
.exit rts
; for the percussion channel, the note played sets the percussion instrument
.percussion move.l #65536,vc_Step(a3) ; sample rate always 1.0
clr.l vc_Index(a3)
move.l a2,vc_Channel(a3) ; back link
addi.b #100,d1 ; percussion instruments
lea Instruments,a0
move.l (a0,d1.w*4),a0 ; instrument record
move.l in_Wave(a0),vc_Wave(a3)
move.l in_Loop(a0),vc_Loop(a3)
move.l in_Length(a0),vc_Length(a3)
move.b in_Flags(a0),vc_Flags(a3)
rts
;------------------------------------------------------------------------
Pitch moveq #15,d1
and.b d0,d1 ; d1 = channel
lea Channels,a0
movea.l (a0,d1.w*4),a2 ; channel record
moveq #0,d1
move.b (a1)+,d1 ; pitch wheel setting
lea PitchTable,a0
move.l (a0,d1.w*4),ch_Pitch(a2)
rts
;------------------------------------------------------------------------
Tempo addq.l #1,a1 ; skip value
rts
;------------------------------------------------------------------------
ChangeCtrl moveq #15,d1
and.b d0,d1 ; d1 = channel
lea Channels,a0
movea.l (a0,d1.w*4),a2 ; channel
move.b (a1)+,d1 ; get controller
moveq #0,d2
move.b (a1)+,d2 ; value
tst.b d1
bne.b .1
; set channel instrument
lea Instruments,a0
move.l (a0,d2.w*4),ch_Instr(a2)
bne.b .0
move.l #QuietInst,ch_Instr(a2)
.0 rts
.1 cmpi.b #3,d1 ; volume?
bne.b .2
; set channel volume
move.b d2,ch_Vol(a2)
rts
.2 cmpi.b #4,d1 ; pan?
bne.b .exit
; set channel pan
move.b d2,ch_Pan(a2)
.exit rts
;------------------------------------------------------------------------
NoEvent rts
;------------------------------------------------------------------------
EndScore btst #4,Flags ; loop?
beq.b .loop
lea _custom,a0
move.w #$0600,intena(a0) ; kill int enable
move.w #$0600,intreq(a0) ; kill request
clr.b MusFlag ; clear mus flag
bclr #2,Flags ; kill playing flag
moveq #0,d0
move.w d0,aud2+ac_vol(a0) ; kill old audio
move.w d0,aud3+ac_vol(a0)
bsr KillAllAud
addq.l #8,a7 ; pop NextEvent, AudioInt
movem.l (a7)+,d2-d6/a2-a4/a6 ; return from interrupt
moveq #0,d0
rts
.loop movea.l MusPtr,a1
moveq #0,d1
move.w 6(a1),d1 ; score start
ror.w #8,d1
adda.l d1,a1 ; a1 = start
clr.l MyTicks ; reset my timer
rts
;------------------------------------------------------------------------
;--------------------------------------------------------------------
cnop 0,4
CreatePool movea.l _SysBase,a1
cmpi.w #39,LIB_VERSION(a1)
blt.b .nopools ; change to bra for debugging
move.l a6,-(sp)
movea.l a1,a6
CALLSYS CreatePool
movea.l (sp)+,a6
rts
.nopools movem.l d2-d7/a2-a6,-(sp)
move.l d0,d4 ; memory attributes
move.l d1,d3 ; amount to allocate when low
move.l d2,d5 ; size of when not to use pool
exg.l d0,d1 ; swap flags and size
movea.l a1,a6
CALLSYS AllocMem ; get first block
movea.l d0,a0
tst.l d0
beq.b .exit ; no memory!
movem.l d3-d5,(a0) ; puddleSize, Flags,Threshold
clr.l 12(a0) ; no next block
lea 24(a0),a1 ; first free location here
move.l a1,16(a0)
subi.l #24,d3 ; for header info
move.l d3,20(a0) ; amount free in this block
.exit movem.l (sp)+,d2-d7/a2-a6
rts
cnop 0,4
DeletePool movea.l _SysBase,a1
cmpi.w #39,LIB_VERSION(a1)
blt.b .nopools ; change to bra for debugging
move.l a6,-(sp)
movea.l a1,a6
CALLSYS DeletePool
movea.l (sp)+,a6
rts
.nopools movem.l d2-d7/a2-a6,-(sp)
move.l a0,d2 ; first block
beq.b .exit ; safety check
movea.l a1,a6
.loop movea.l d2,a1 ; pointer to block
move.l (a1),d0 ; size of block
move.l 12(a1),d2 ; next block
CALLSYS FreeMem
tst.l d2
bne.b .loop
.exit movem.l (sp)+,d2-d7/a2-a6
rts
cnop 0,4
AllocPooled movea.l _SysBase,a1
cmpi.w #39,LIB_VERSION(a1)
blt.b .nopools ; change to bra for debugging
move.l a6,-(sp)
movea.l a1,a6
CALLSYS AllocPooled
movea.l (sp)+,a6
rts
.nopools movem.l d2-d7/a2-a6,-(sp)
move.l a0,d2
beq.b .exit ; safety check
addq.l #3,d0
andi.b #$FC,d0 ; long align size
movea.l a1,a6
cmp.l 8(a0),d0 ; check threshold
blt.b .chkpuddles ; allocate from puddles
addi.l #24,d0 ; for header
move.l d0,d3 ; save size
move.l 4(a0),d1 ; mem attrs
CALLSYS AllocMem
movea.l d0,a0
tst.l d0
beq.b .exit ; no memory
move.l d3,(a0) ; size of block
clr.l 20(a0) ; no free space in here
movea.l d2,a1 ; pool header
move.l 12(a1),d1
move.l a0,12(a1) ; splice in block
move.l d1,12(a0) ; relink next block
lea 24(a0),a0 ; skip over header
.exit move.l a0,d0
movem.l (sp)+,d2-d7/a2-a6
rts
cnop 0,4
.chkpuddles cmp.l 20(a0),d0 ; check free space
blt.b .gotspace
movea.l 12(a0),a0 ; next block
move.l a0,d1
bne.b .chkpuddles
; not enough free space in existing puddles, create another
move.l d0,d6 ; save size
movea.l d2,a0 ; pool header
movem.l (a0),d3-d5
movem.l (a0),d0-d1
CALLSYS AllocMem ; get block
movea.l d0,a0
tst.l d0
beq.b .out ; no memory!
movea.l d2,a1 ; pool header
movem.l d3-d5,(a0) ; puddleSize, Flags,Threshold
move.l 12(a1),12(a0) ; next block
move.l a0,12(a1) ; splice in block
lea 24(a0),a1 ; first free location here
move.l a1,16(a0)
subi.l #24,d3 ; for header info
move.l d3,20(a0) ; amount free in this block
move.l d6,d0 ; restore size
.gotspace sub.l d0,20(a0) ; sub from amount free
bmi.b .err ; threshold >= puddlesize!
move.l 16(a0),a1 ; free space
add.l d0,16(a0) ; next free space
movea.l a1,a0
bra.b .out
.err add.l d0,20(a0) ; restore free space
moveq #0,d0
suba.l a0,a0 ; no memory
.out move.l a0,d0
movem.l (sp)+,d2-d7/a2-a6
rts
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;------------------------------------------------------------------------
MUSMemPtr dc.l 0
MUSMemSize dc.l 0
;------------------------------------------------------------------------
midifileproblem dc.b "Error opening MIDI_Instruments file!",0
dosproblem dc.b "Error reading MIDI_Instruments file!",0
memproblem dc.b "Not enough memory for music!",0
notmusfile dc.b "Music lump in WAD file is not .MUS format!",0
damagedfile dc.b "Damaged MIDI_Instruments or WAD file!",0
cantopenaud dc.b "Can't open audio.device for music!",0
cantgetchan dc.b "Can't allocate channels for music!",0
cnop 0,4
;------------------------------------------------------------------------
; bit 0 = close, bit 1 = file loaded, bit 2 = playing, bit 3 = paused
; bit 4 = loop, bit 5 = attention, bit 6 = gadget down, bit 7 = rev/FF
Flags dc.b 0
Flags2 dc.b 0 ; backup of Flags
; bit 0,1 = dotick
Flags3 dc.b 0
cnop 0,4
per dc.w 0
per2 dc.w 0 ; period for 11048 Hz
;------------------------------------------------------------------------
cnop 0,4
EventTable dc.w Release-EventTable
dc.w PlayNote-EventTable
dc.w Pitch-EventTable
dc.w Tempo-EventTable
dc.w ChangeCtrl-EventTable
dc.w NoEvent-EventTable
dc.w EndScore-EventTable
dc.w NoEvent-EventTable
;------------------------------------------------------------------------
cnop 0,4
looping dc.l 0
musicdies dc.l -1
MyTicks dc.l 0
PrevDelay dc.l 0
AudioPort dc.l 0,0
dc.b NT_MSGPORT,0 ; LN_TYPE, LN_PRI
dc.l 0 ; LN_NAME
dc.b PA_SIGNAL ; mp_Flags
dc.b 0 ; mp_SigBit
AudioTask dc.l 0 ; mp_SigTask
.1 dc.l .2
.2 dc.l 0
dc.l .1
cnop 0,4
AudioIO dc.l 0,0
dc.b NT_REPLYMSG,0 ; LN_TYPE, LN_PRI
dc.l 0 ; LN_NAME
dc.l AudioPort ; mn_ReplyPort
dc.w 68 ; mn_Length
dc.l 0 ; IO_DEVICE
dc.l 0 ; IO_UNIT
dc.w 0 ; IO_COMMAND
dc.b 0 ; IO_FLAGS
dc.b 0 ; IO_ERROR
dc.w 0 ; ioa_AllocKey
dc.l 0 ; ioa_Data
dc.l 0 ; ioa_Length
dc.w 0 ; ioa_Period
dc.w 0 ; ioa_Volume
dc.w 0 ; ioa_Cycles
dc.l 0,0 ; ioa_WriteMsg
dc.b 0,0
dc.l 0
dc.l 0
dc.w 0
cnop 0,4
AInt2 dc.l 0,0
dc.b NT_INTERRUPT,0 ; LN_TYPE, LN_PRI
dc.l TPortName ; LN_NAME
dc.l 0 ; IS_DATA
dc.l AudioINT2 ; IS_CODE
MusPtr dc.l 0
MusIndex dc.l 0
MusDelay dc.l 0
OldAInt2 dc.l 0
AudioAlloc dc.b $0c ; Amiga channels to allocate
AudioName dc.b 'audio.device',0
TPortName dc.b 'ADoom-MUS',0
AudioOK dc.b 0
AudioCh dc.b 0
musicarg dc.b "-music",0
;--------------------------------------
CNOP 0,4
; bit set if voice is in use (0-15=music voices,16-31=sfx voices)
VoiceAvail dc.l 0
; bit 0 = stop processing, bit 1 = buffer indicator
MusFlag dc.b 0
;--------------------------------------------------------------------
CNOP 0,4
NoteTable dc.l 65536/64,69433/64,73562/64,77936/64,82570/64,87480/64,92682/64,98193/64,104032/64,110218/64,116772/64,123715/64
dc.l 65536/32,69433/32,73562/32,77936/32,82570/32,87480/32,92682/32,98193/32,104032/32,110218/32,116772/32,123715/32
dc.l 65536/16,69433/16,73562/16,77936/16,82570/16,87480/16,92682/16,98193/16,104032/16,110218/16,116772/16,123715/16
dc.l 65536/8,69433/8,73562/8,77936/8,82570/8,87480/8,92682/8,98193/8,104032/8,110218/8,116772/8,123715/8
dc.l 65536/4,69433/4,73562/4,77936/4,82570/4,87480/4,92682/4,98193/4,104032/4,110218/4,116772/4,123715/4
dc.l 65536/2,69433/2,73562/2,77936/2,82570/2,87480/2,92682/2,98193/2,104032/2,110218/2,116772/2,123715/2
dc.l 65536,69433,73562,77936,82570,87480,92682,98193,104032,110218,116772,123715
dc.l 65536*2,69433*2,73562*2,77936*2,82570*2,87480*2,92682*2,98193*2,104032*2,110218*2,116772*2,123715*2
dc.l 65536*4,69433*4,73562*4,77936*4,82570*4,87480*4,92682*4,98193*4,104032*4,110218*4,116772*4,123715*4
dc.l 65536*8,69433*8,73562*8,77936*8,82570*8,87480*8,92682*8,98193*8,104032*8,110218*8,116772*8,123715*8
dc.l 65536*16,69433*16,73562*16,77936*16,82570*16,87480*16,92682*16,98193*16
;------------------------------------------------------------------------
PitchTable:
pitch_ix SET 128
REPT 128
dc.l -3678*pitch_ix/64
pitch_ix SET pitch_ix-1
ENDR
REPT 128
dc.l 3897*pitch_ix/64
pitch_ix SET pitch_ix+1
ENDR
;------------------------------------------------------------------------
CNOP 0,4
AudioCh2Buf dc.l chipbuffer2
AudioCh2Ptr dc.l chipbuffer2
AudioCh2Vol dc.w 64
CNOP 0,4
AudioCh3Buf dc.l chipbuffer3
AudioCh3Ptr dc.l chipbuffer3
AudioCh3Vol dc.w 64
;------------------------------------------------------------------------
STRUCTURE MusChannel,0
APTR ch_Instr
APTR ch_Map
ULONG ch_Pitch
BYTE ch_Vol
BYTE ch_Pan
CNOP 0,4
Channels dc.l Channel0,Channel1,Channel2,Channel3
dc.l Channel4,Channel5,Channel6,Channel7
dc.l Channel8,Channel9,Channel10,Channel11
dc.l Channel12,Channel13,Channel14,Channel15
CNOP 0,4
Channel0 dc.l 0 ; instrument
dc.l Channel0Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel1 dc.l 0 ; instrument
dc.l Channel1Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel2 dc.l 0 ; instrument
dc.l Channel2Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel3 dc.l 0 ; instrument
dc.l Channel3Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel4 dc.l 0 ; instrument
dc.l Channel4Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel5 dc.l 0 ; instrument
dc.l Channel5Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel6 dc.l 0 ; instrument
dc.l Channel6Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel7 dc.l 0 ; instrument
dc.l Channel7Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel8 dc.l 0 ; instrument
dc.l Channel8Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel9 dc.l 0 ; instrument
dc.l Channel9Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel10 dc.l 0 ; instrument
dc.l Channel10Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel11 dc.l 0 ; instrument
dc.l Channel11Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel12 dc.l 0 ; instrument
dc.l Channel12Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel13 dc.l 0 ; instrument
dc.l Channel13Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel14 dc.l 0 ; instrument
dc.l Channel14Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel15 dc.l 0 ; instrument
dc.l Channel15Map ; note to voice map
dc.l 0 ; pitch wheel setting
dc.b 0 ; volume
dc.b 0 ; pan setting
CNOP 0,4
Channel0Map dcb.b 128,0
Channel1Map dcb.b 128,0
Channel2Map dcb.b 128,0
Channel3Map dcb.b 128,0
Channel4Map dcb.b 128,0
Channel5Map dcb.b 128,0
Channel6Map dcb.b 128,0
Channel7Map dcb.b 128,0
Channel8Map dcb.b 128,0
Channel9Map dcb.b 128,0
Channel10Map dcb.b 128,0
Channel11Map dcb.b 128,0
Channel12Map dcb.b 128,0
Channel13Map dcb.b 128,0
Channel14Map dcb.b 128,0
Channel15Map dcb.b 128,0
;--------------------------------------
STRUCTURE AudioVoice,0
APTR vc_Next
APTR vc_Channel
APTR vc_Wave
ULONG vc_Index
ULONG vc_Step
ULONG vc_Loop
ULONG vc_Length
BYTE vc_Vol
BYTE vc_Flags ; b7 = SFX, b1 = RLS, b0 = EN
CNOP 0,4
Voices dc.l Voice0,Voice1,Voice2,Voice3
dc.l Voice4,Voice5,Voice6,Voice7
dc.l Voice8,Voice9,Voice10,Voice11
dc.l Voice12,Voice13,Voice14,Voice15
CNOP 0,4
Voice0 dc.l Voice1
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice1 dc.l Voice2
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice2 dc.l Voice3
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice3 dc.l Voice4
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice4 dc.l Voice5
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice5 dc.l Voice6
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice6 dc.l Voice7
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice7 dc.l Voice8
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice8 dc.l Voice9
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice9 dc.l Voice10
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice10 dc.l Voice11
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice11 dc.l Voice12
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice12 dc.l Voice13
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice13 dc.l Voice14
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice14 dc.l Voice15
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
CNOP 0,4
Voice15 dc.l 0
dc.l 0 ; channel back-link
dc.l 0 ; instrument wave data
dc.l 0 ; sample index
dc.l 0 ; sample rate
dc.l 0 ; instrument loop point
dc.l 0 ; instrument data length
dc.b 0 ; voice volume scale
dc.b 0 ; voice flags
;--------------------------------------
STRUCTURE InstrumentRec,0
APTR in_Wave
ULONG in_Loop
ULONG in_Length
BYTE in_Flags
BYTE in_Base
CNOP 0,4
Instruments dcb.l 256,0
CNOP 0,4
QuietInst dc.l 0
dc.l 0
dc.l 0
dc.b 0
dc.b 0
CNOP 0,4
InstrHandle dc.l 0
InstrFile dc.l InstrName
InstrPool dc.l 0
InstrName dc.b 'PROGDIR:MIDI_Instruments',0
CNOP 0,4
validInstr dc.b %11111111 ; (00-07) Piano
dc.b %11111111 ; (08-0F) Chrom Perc
dc.b %11111111 ; (10-17) Organ
dc.b %11111111 ; (18-1F) Guitar
dc.b %11111111 ; (20-27) Bass
dc.b %11111111 ; (28-2F) Strings
dc.b %11111111 ; (30-37) Ensemble
dc.b %11111111 ; (38-3F) Brass
dc.b %11111111 ; (40-47) Reed
dc.b %11111111 ; (48-4F) Pipe
dc.b %11111111 ; (50-57) Synth Lead
dc.b %11111111 ; (58-5F) Synth Pad
dc.b %11111111 ; (60-67) Synth Effects
dc.b %11111111 ; (68-6F) Ethnic
dc.b %11111111 ; (70-77) Percussive
dc.b %11111111 ; (78-7F) SFX
dc.b %00000001 ; (80-87) invalid,Drum
dc.b %11111111 ; (88-8F) Drums/Clap/Hi-Hat
dc.b %11111111 ; (90-97) Hi-Hats/Toms/Cymb1
dc.b %11111111 ; (98-9F) Cymbals/Bells/Slap
dc.b %11111111 ; (A0-A7) Bongos/Congas/Timb
dc.b %11111111 ; (A8-AF) Agogo/Whistles/Gui
dc.b %11111100 ; (B0-B7) Claves/Block/Trian
dc.b %00000000 ; (B8-BF) invalid
dc.b %00000000 ; (C0-C7)
dc.b %00000000 ; (C8-CF)
dc.b %00000000 ; (D0-D7)
dc.b %00000000 ; (D8-DF)
dc.b %00000000 ; (E0-E7)
dc.b %00000000 ; (E8-EF)
dc.b %00000000 ; (F0-F7)
dc.b %00000000 ; (F8-FF)
;--------------------------------------------------------------------
section PlayMusChip,data_c
ClearBuf dcb.b 160,0
chipbuffer2 dcb.b 320,0
chipbuffer3 dcb.b 320,0
;------------------------------------------------------------------------
section PlayMusBSS,bss
EventBlocks ds.w 32768
tempAudio ds.b 160
;------------------------------------------------------------------------
end